﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace FerrScript
{
    class CompilerInstruction
    {
        #region Fields
        internal ScriptValue           value;
        internal CompilerInstruction[] instructions;
        #endregion

        #region Methods
        public ScriptValue Evaluate()
        { 
            ScriptValue retValue = new ScriptValue(0);
            switch (value.type)
            {
                case ScriptValueType.Number:
                case ScriptValueType.String:
                    {
                        retValue = new ScriptValue(value);
                    } break;
                case ScriptValueType.Delegate:
                    {
                        retValue = ((ScriptFunctionDelegate)value.value)(instructions);
                    } break;
                case ScriptValueType.Variable:
                    {
                        retValue = ((ScriptVariable)value.value).value;
                    } break;
                case ScriptValueType.FunctionCall:
                    {
                        CompiledFunction func = (CompiledFunction)value.value;

                        // set up the function's arguments
                        for (int i=0;i<func.arguments.Length;i++)
                            func.arguments[i].value = instructions[i].Evaluate();

                        // call the function instructions
                        for (int i = func.arguments.Length; i < func.rootInstruction.instructions.Length; i++)
                            retValue = func.rootInstruction.instructions[i].Evaluate();
                    } break;
                default:
                    {
                        FerrScriptCompiler.Inst.ThrowException("Unsupported ScriptValueType was evaluated! " + value);
                    } break;
            }

            return retValue;
        }
        #endregion

        #region Overrides
        public override string ToString()
        {
            return value.ToString();
        }
        #endregion
    }
}
